
#include "stdafx.h"
#include "ConstDef.h"
#include "ReloadCode.h"
#include "ReloadPacket.h"
#include "ReloadApp.h"
#include "ReloadPacket.h"
#include "ReloadOverlay.h"
#include "ReloadNetworkDataHandler.h"

namespace reload
{
	ReloadNetworkDataContext::ReloadNetworkDataContext()
	:pReloadPacket_(),pWildcardElement_()
	{

	}

	ReloadNetworkDataContext::ReloadNetworkDataContext( boost::shared_ptr<ReloadNetworkDataContext> _pReloadNetworkDataContext )
	:asyframe::UdpHandlerContext(_pReloadNetworkDataContext),pReloadPacket_(),pWildcardElement_(_pReloadNetworkDataContext->pWildcardElement_)
	{
		if(_pReloadNetworkDataContext->pReloadPacket_)
		{
			pReloadPacket_.reset(new ReloadPacket(*_pReloadNetworkDataContext->pReloadPacket_));
			R0(pReloadPacket_->attachRootElement());
		}
	}

	ReloadNetworkDataContext::~ReloadNetworkDataContext()
	{
		pReloadPacket_.reset();
		pWildcardElement_.reset();
	}

	//////////////////////////////////////////////////////////////////////////////////////

	IReloadNetworkDataAction::IReloadNetworkDataAction()
	{

	}

	IReloadNetworkDataAction::~IReloadNetworkDataAction()
	{

	}

	retT IReloadNetworkDataAction::onRead( boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext, std::size_t _bytesTransferred, const boost::system::error_code& e, std::size_t _timeoutCount )
	{
		R(asyframe::ITcpAction::onRead(_pDataHandlerContext, _bytesTransferred, e, _timeoutCount));
		RETSUCCESS;
	}

	retT IReloadNetworkDataAction::onWrite( boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext, std::size_t _bytesTransferred, const boost::system::error_code& e, std::size_t _timeoutCount )
	{
		R(asyframe::ITcpAction::onWrite(_pDataHandlerContext, _bytesTransferred, e, _timeoutCount));
		RETSUCCESS;
	}

	retT IReloadNetworkDataAction::onConnect( boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext, const boost::system::error_code& e, std::size_t _timeoutCount )
	{
		R(asyframe::ITcpAction::onConnect(_pDataHandlerContext, e, _timeoutCount));
		RETSUCCESS;
	}

	////////////////////////////////////////////////////////////////////////////////////

	ReloadNetworkDataHandler::ReloadNetworkDataHandler()
	:asyframe::DataHandler(),pTcpHandler_()
	{

	}

	ReloadNetworkDataHandler::~ReloadNetworkDataHandler()
	{
		pTcpHandler_.reset();
	}

	retT ReloadNetworkDataHandler::asyncRead( boost::shared_ptr<asyframe::IoBuffer> _pBuffers, boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext /*= boost::shared_ptr<asyframe::DataHandlerContext>()*/, asyframe::DataCallBackFunType _dataCallBackFun /*= NULL*/ )
	{
		R(pTcpHandler_->asyncRead(_pBuffers, _pDataHandlerContext, _dataCallBackFun));
		RETSUCCESS;
	}

	retT ReloadNetworkDataHandler::asyncWrite( boost::shared_ptr<asyframe::IoBuffer> _pBuffers, boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext /*= boost::shared_ptr<asyframe::DataHandlerContext>()*/, asyframe::DataCallBackFunType _dataCallBackFun /*= NULL*/ )
	{
		R(pTcpHandler_->asyncWrite(_pBuffers, _pDataHandlerContext, _dataCallBackFun));
		RETSUCCESS;
	}

	retT ReloadNetworkDataHandler::asyncConnect( const void* _pEndpoint, boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext /*= boost::shared_ptr<asyframe::DataHandlerContext>()*/, asyframe::BaseCallBackFunType _dataCallBackFun /*= NULL*/ )
	{
		R(pTcpHandler_->asyncConnect(_pEndpoint, _pDataHandlerContext, _dataCallBackFun));
		RETSUCCESS;
	}

	retT ReloadNetworkDataHandler::asyncConnect( const std::string& _address, unsigned short _port, boost::shared_ptr<asyframe::DataHandlerContext> _pDataHandlerContext /*= boost::shared_ptr<asyframe::DataHandlerContext>()*/, asyframe::BaseCallBackFunType _dataCallBackFun /*= NULL*/ )
	{
		R(pTcpHandler_->asyncConnect(_address, _port, _pDataHandlerContext, _dataCallBackFun));
		RETSUCCESS;
	}

	retT ReloadNetworkDataHandler::init()
	{
		R(asyframe::DataHandler::init());
		pTcpHandler_.reset(new asyframe::TcpHandler());
		R(pTcpHandler_->attachHandlerOwner(shared_from_this()));
		RETSUCCESS;
	}

	boost::shared_ptr<boost::asio::ip::tcp::socket> ReloadNetworkDataHandler::getTcpSocket()
	{
		return pTcpHandler_->getSocket();
	}

	retT ReloadNetworkDataHandler::prepareIceCandidates( boost::shared_ptr<ReloadOverlay> _pReloadOverlay, boost::shared_ptr<AttachReqAns> _pAttachReqAns )
	{
		if(!_pReloadOverlay || !_pAttachReqAns)
			RET(ERROR_COMMON_SHARED_PTR_NULL);
		boost::shared_ptr<boost::asio::ip::tcp::endpoint> pLocalEndpoint(new boost::asio::ip::tcp::endpoint(
			_pReloadOverlay->listeningIpAddressPort_.addr_, 0));
		pTcpHandler_->setLocalEndpoint(pLocalEndpoint);
		R(pTcpHandler_->bind(getWorker()));
		*pLocalEndpoint = pTcpHandler_->getSocket()->local_endpoint();
		pTcpHandler_->setLocalEndpoint(pLocalEndpoint);
		IceCandidate selfIceCandidate;
		selfIceCandidate.type_ = CandType_Host;
		selfIceCandidate.addrPort_ = IpAddressPort(pTcpHandler_->getSocket()->local_endpoint().address(), pTcpHandler_->getSocket()->local_endpoint().port());
		_pAttachReqAns->candidates_.array_.push_back(selfIceCandidate);
		RETSUCCESS;
	}
} /*namespace reload*/
